using Microsoft.Extensions.Logging;
using SumerCoreDevOps.ExecuteNodeApi.Services;
using SumerCoreDevOps.Shared.Enums;
using SumerCoreDevOps.Shared.Models;
using SumerCoreDevOps.Shared.Models.Messages;
using System.Diagnostics;
using System.Text;
using System.Text.Json;

namespace SumerCoreDevOps.ExecuteNodeApi.Handlers;

/// <summary>
/// 构建处理器
/// </summary>
public class BuildHandler : IStepHandler
{
    private readonly ILogger<BuildHandler> _logger;
    private readonly TaskExecutor _taskExecutor;
    private readonly ProjectTypeDetector _projectTypeDetector;
    private readonly EnvironmentDetector _environmentDetector;
    private readonly EnvironmentInstaller _environmentInstaller;

    public BuildHandler(
        ILogger<BuildHandler> logger,
        TaskExecutor taskExecutor,
        ProjectTypeDetector projectTypeDetector,
        EnvironmentDetector environmentDetector,
        EnvironmentInstaller environmentInstaller)
    {
        _logger = logger;
        _taskExecutor = taskExecutor;
        _projectTypeDetector = projectTypeDetector;
        _environmentDetector = environmentDetector;
        _environmentInstaller = environmentInstaller;
    }

    public async Task<StepExecutionResult> ExecuteAsync(WorkflowStepDispatchMessage message)
    {
        try
        {
            // 声明项目类型变量，用于后续日志记录
            ProjectType projectType = ProjectType.Unknown;

            // 步骤1：从项目文件中自动检测环境需求（包含版本号）
            var autoDetectedReq = _projectTypeDetector.DetectProjectRequirement(message.WorkDirectory);

            if (autoDetectedReq != null)
            {
                // 同时检测项目类型用于日志
                projectType = _projectTypeDetector.DetectProjectType(message.WorkDirectory);

                _logger.LogInformation("从项目文件自动检测到环境需求: {Name} {Version}",
                    autoDetectedReq.Name,
                    autoDetectedReq.MinVersion ?? "(任意版本)");

                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId,
                    $"📦 从项目文件检测到: {autoDetectedReq.Name}" +
                    (autoDetectedReq.MinVersion != null ? $" {autoDetectedReq.MinVersion}" : ""));

                // 步骤2：检查并安装环境
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId,
                    $"🔍 检查环境: {autoDetectedReq.Name}" +
                    (autoDetectedReq.MinVersion != null ? $" (>= {autoDetectedReq.MinVersion})" : ""));

                var (success, envMessage) = await _environmentInstaller.EnsureEnvironmentAsync(
                    autoDetectedReq,
                    message.TaskId,
                    message.StepId);

                if (!success)
                {
                    return new StepExecutionResult
                    {
                        Success = false,
                        ErrorMessage = envMessage
                    };
                }
            }
            else
            {
                // 如果无法自动检测，使用用户配置或基本检测
                projectType = _projectTypeDetector.DetectProjectType(message.WorkDirectory);
                _logger.LogInformation("检测到项目类型: {ProjectType}", projectType);
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, $"📦 检测到项目类型: {projectType}");

                var requirement = GetEnvironmentRequirement(projectType, message.StepConfig);
                if (requirement != null)
                {
                    await _taskExecutor.SendLogAsync(message.TaskId, message.StepId,
                        $"🔍 检查环境: {requirement.Name}" +
                        (requirement.MinVersion != null ? $" (>= {requirement.MinVersion})" : ""));

                    var (success, envMessage) = await _environmentInstaller.EnsureEnvironmentAsync(
                        requirement,
                        message.TaskId,
                        message.StepId);

                    if (!success)
                    {
                        return new StepExecutionResult
                        {
                            Success = false,
                            ErrorMessage = envMessage
                        };
                    }
                }
            }

            // 步骤3：获取或检测构建命令
            var buildCommand = message.Command;
            if (string.IsNullOrEmpty(buildCommand))
            {
                _logger.LogInformation("构建命令未指定，尝试自动检测项目类型...");
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, "构建命令未指定，正在自动检测项目类型...");

                buildCommand = _projectTypeDetector.DetectAndGetBuildCommand(message.WorkDirectory);

                if (string.IsNullOrEmpty(buildCommand))
                {
                    var errorMsg = "无法检测到项目类型，请手动指定构建命令";
                    await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, errorMsg, "Error");
                    return new StepExecutionResult
                    {
                        Success = false,
                        ErrorMessage = errorMsg
                    };
                }

                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, $"已自动检测到构建命令: {buildCommand}");
            }

            _logger.LogInformation("执行构建命令: {Command}", buildCommand);

            // 步骤4：执行构建
            await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, $"🔨 开始执行构建命令: {buildCommand}");

            var result = await ExecuteCommandAsync(buildCommand, message.WorkDirectory, message.TimeoutSeconds, message);

            if (result.ExitCode == 0)
            {
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, "✓ 构建成功");
                return new StepExecutionResult
                {
                    Success = true,
                    Progress = 100,
                    OutputContext = new Dictionary<string, string>
                    {
                        ["BUILD_OUTPUT"] = result.Output,
                        ["BUILD_TIME"] = DateTime.UtcNow.ToString("o"),
                        ["PROJECT_TYPE"] = projectType.ToString()
                    }
                };
            }
            else
            {
                return new StepExecutionResult
                {
                    Success = false,
                    ErrorMessage = $"构建失败 (Exit Code: {result.ExitCode}): {result.Output}"
                };
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "构建处理器执行失败");
            return new StepExecutionResult
            {
                Success = false,
                ErrorMessage = ex.Message
            };
        }
    }

    /// <summary>
    /// 根据项目类型获取环境需求
    /// </summary>
    private EnvironmentRequirement? GetEnvironmentRequirement(ProjectType projectType, string stepConfig)
    {
        try
        {
            // 尝试从配置中解析环境需求
            if (!string.IsNullOrEmpty(stepConfig) && stepConfig != "{}")
            {
                var config = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(stepConfig);
                if (config != null)
                {
                    if (config.TryGetValue("requiredEnvironment", out var envElement))
                    {
                        return JsonSerializer.Deserialize<EnvironmentRequirement>(envElement.GetRawText());
                    }

                    // 兼容旧版配置：language 和 version
                    if (config.TryGetValue("language", out var langElement))
                    {
                        var language = langElement.GetString();
                        var version = config.TryGetValue("version", out var verElement) ? verElement.GetString() : null;

                        if (!string.IsNullOrEmpty(language))
                        {
                            return new EnvironmentRequirement
                            {
                                Name = language,
                                MinVersion = version,  // 用户配置的版本
                                IsRequired = true
                            };
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex, "解析环境需求失败，将只检查环境是否存在");
        }

        // 如果没有配置，返回基本环境需求（不限定版本，只检查是否安装）
        return projectType switch
        {
            ProjectType.DotNet => new EnvironmentRequirement { Name = "dotnet", IsRequired = true },
            ProjectType.JavaMaven => new EnvironmentRequirement { Name = "java", IsRequired = true },
            ProjectType.JavaGradle => new EnvironmentRequirement { Name = "java", IsRequired = true },
            ProjectType.NodeJsNpm => new EnvironmentRequirement { Name = "node", IsRequired = true },
            ProjectType.NodeJsYarn => new EnvironmentRequirement { Name = "node", IsRequired = true },
            ProjectType.NodeJsPnpm => new EnvironmentRequirement { Name = "node", IsRequired = true },
            ProjectType.Python => new EnvironmentRequirement { Name = "python", IsRequired = true },
            ProjectType.Rust => new EnvironmentRequirement { Name = "rust", IsRequired = true },
            ProjectType.Go => new EnvironmentRequirement { Name = "go", IsRequired = true },
            _ => null
        };
    }

    private async Task<(int ExitCode, string Output)> ExecuteCommandAsync(
        string command,
        string workingDirectory,
        int timeoutSeconds,
        WorkflowStepDispatchMessage message)
    {
        var output = new StringBuilder();

        // 解析命令和参数
        var parts = command.Split(' ', 2);
        var fileName = parts[0];
        var arguments = parts.Length > 1 ? parts[1] : string.Empty;

        var startInfo = new ProcessStartInfo
        {
            FileName = fileName,
            Arguments = arguments,
            WorkingDirectory = workingDirectory,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        using var process = new Process { StartInfo = startInfo };

        process.OutputDataReceived += async (sender, e) =>
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                output.AppendLine(e.Data);
                _logger.LogInformation("Build: {Line}", e.Data);

                // 发送日志到控制面板
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, e.Data);
            }
        };

        process.ErrorDataReceived += async (sender, e) =>
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                output.AppendLine(e.Data);
                _logger.LogWarning("Build Error: {Line}", e.Data);

                // 发送错误日志到控制面板
                await _taskExecutor.SendLogAsync(message.TaskId, message.StepId, e.Data, "Warning");
            }
        };

        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();

        using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
        await process.WaitForExitAsync(cts.Token);

        return (process.ExitCode, output.ToString());
    }
}
